拾遗 - UIKit

UIView 和 CALayer

联系

在每一个UIView实例当中,都有一个默认的支持图层layer,UIView负责创建并且管理这个图层。实际上 UIView之所以能够显示,就是因为它里面有这个一个层,才具有显示的功能 ,UIView仅仅是对它的一层封装,实现了CALayer的delegate,提供了处理事件交互的具体功能,还有动画底层方法的高级API。可以说CALayer是UIView的内部实现细节

  • UIView 是CALayer轻量级封装 使用CALayer不会带来显著的性能优势 iOS MacOS CALayer无缝衔接

区别

  • 首先UIView可以响应事件,CALayer不可以响应事件
  • 一个 Layer 的 frame 是由它的anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame
  • UIView主要是对显示内容的管理而 CALayer 主要侧重显示内容的绘制
    在做
  • iOS 动画的时候,修改非 RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会。

图像显示原理

分工

  • CPU:计算视图frame 输出位图
  • CPU:绘制纹理、图层渲染
  • 结果放到帧缓存区(frame buffer)
  • 再由视频控制器根据vsync信号在指定时间之前去提取帧缓冲区的屏幕显示内容

卡顿分析

  • UI渲染时间过长
  • 计算过多,主线程阻塞,无法渲染UI界面
  • 网络请求慢 UI层无响应
  • 总结 <60fps 1/60 如果CPU和GPU加起来的处理时间超过了16.7ms,就会造成掉帧甚至卡顿

CPU资源消耗分析

  • 对象创建:主线程创建对象、读取文件等
  • 对象调整:frame、bounds、transform及视图层次等属性调整很耗费CPU资源。尽量减少不必要属性的修改,尽量避免调整视图层次、添加和移除视图
  • 布局计算:autolayout 提前算好布局
  • 文本渲染、图片解码:当用UIImage或CGImageSource创建图片时,图片数据并不会立刻解码。图片设置到UIImageView或CALayer.contents中去,并且CALayer被提交到GPU前,CGImage中的数据才会得到解码。这一步是发生在主线程的,并且不可避免。
  • - SD_WebImage处理方式:在后台线程先把图片绘制到CGBitmapContext中,然后从Bitmap直接创建图片
  • 图像绘制

CPU资源消耗分析

  • 纹理混合:尽量减少短时间内大量图片的显示,尽可能将多张图片合成一张进行显示。
  • 视图混合:尽量减少视图层次和数量,并在不透明的视图里标明opaque属性以避免无用的Alpha通道合成。
  • 图形生成:尽量避免离屏渲染,尽量采用异步绘制,尽量避免使用圆角、阴影、遮罩等属性。必要时用静态图片实现展示效果,也可尝试光栅化缓存复用属性